﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Bigger.Test
{
    public class Logger
    {
        private string logPath { get; set; }
        public Logger(string logPath)
        {
            this.logPath = logPath;
        }
        public void Info(string title, string message, params string[] tagValues)
        {
            CreateLog(LogLevel.Info, title, message, tagValues);
        }
        public void Info(string title, Exception exception, params string[] tagValues)
        {
            CreateLog(LogLevel.Info, title, CreateMessage(exception), tagValues);
        }
        public void Warn(string title, string message, params string[] tagValues)
        {
            CreateLog(LogLevel.Warn, title, message, tagValues);
        }
        public void Warn(string title, Exception exception, params string[] tagValues)
        {
            CreateLog(LogLevel.Warn, title, CreateMessage(exception), tagValues);
        }
        public void Error(string title, string message, params string[] tagValues)
        {
            CreateLog(LogLevel.Error, title, message, tagValues);
        }
        public void Error(string title, Exception exception, params string[] tagValues)
        {
            CreateLog(LogLevel.Error, title, CreateMessage(exception), tagValues);
        }
        /// <summary>
        /// 创建日志消息
        /// </summary>
        /// <param name="exception"></param>
        /// <returns></returns>
        public string CreateMessage(Exception exception)
        {
            if (exception == null)
            {
                return null;
            }
            return exception.ToString();
        }
        /// <summary>
        /// 创建 Tags
        /// </summary>
        /// <param name="tagValues">Tags</param>
        /// <returns></returns>
        private Dictionary<string, string> CreateTags(params string[] tagValues)
        {
            Dictionary<string, string> tags = new Dictionary<string, string>();

            if (null != tagValues && 0 < tagValues.Length)
            {
                for (int i = 0; i < tagValues.Length; i++)
                {
                    tags["Key" + i.ToString()] = tagValues[i];
                }
            }

            return tags;
        }
        /// <summary>
        /// 创建Log
        /// </summary>
        /// <param name="logLevel"></param>
        /// <param name="title"></param>
        /// <param name="message"></param>
        /// <param name="tagValues"></param>
        private void CreateLog(LogLevel logLevel, string title, string message, params string[] tagValues)
        {

            StringBuilder sb = new StringBuilder();

            sb.AppendLine(string.Format("====={0} start=====", logLevel));
            sb.AppendLine(string.Format("logtime:{0}", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")));
            string tags = string.Join(";", CreateTags(tagValues).Select(kv => string.Format("{0}={1}", kv.Key, kv.Value)));
            sb.AppendLine(string.Format("tags:{0}", tags));
            sb.AppendLine(string.Format("title:{0}", title));
            sb.AppendLine(string.Format("message:{0}", message));
            sb.AppendLine(string.Format("====={0} end=====", logLevel));
            sb.AppendLine();

            string contents = sb.ToString();

            switch (logLevel)
            {
                case LogLevel.Info:
                    Console.ResetColor();
                    break;
                case LogLevel.Warn:
                    Console.ForegroundColor = ConsoleColor.Yellow;
                    break;
                case LogLevel.Error:
                    Console.ForegroundColor = ConsoleColor.Red;
                    break;
            }

            Console.WriteLine(contents);

            if (string.IsNullOrWhiteSpace(logPath))
            {
                return;
            }

            File.AppendAllText(logPath, contents);
        }

        private enum LogLevel
        {
            Info,
            Warn,
            Error,
        }
    }
}
